﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Dict.DataModel;
using ProtoBuf.Message;
using UnityEngine.SceneManagement;
using AssetLoad;
namespace Room
{
    public class RoomCopy : RoomBase
    {
        #region data
        TableCopyMission missionData;
        string deadMonster;
        #endregion

        public List<string> deadMonsters = new List<string>();

        public bool missionLoaded;

        public override SceneType GetSceneType()
        {
            return SceneType.COPY;
        }

        public override void Init()
        {
            base.Init();

            inited = true;
            missionLoaded = false;
        }
        

        protected override void Tick()
        {
            smallMap.Tick();
            if (missionLoaded)
            {
                charactorManager.Tick();
            }
        }

        protected override void OnEnter(params object[] param)
        {
            this.gameObject.SetActive(true);

            if(StaticData.isRelogin)
            {
                StaticData.isRelogin = false;
                charactorManager.ClearAll();
                deadMonsters.Clear();
                missionLoaded = false;
                smallMap.HideMiniMap();
                smallMap.Unload();
            }

            if (!inited)
            {
                Init();
            }


            deadMonster = null;
            if (param.Length >= 1)
            {
                deadMonster = (string)param[0];
                if (!string.IsNullOrEmpty(deadMonster))
                {
                    deadMonsters.Add(deadMonster);
                    charactorManager.DestroyCharactor(deadMonster);

                }
            }
            //selfEnter = false;
            //if (param.Length >= 2)
            //{
            //    selfEnter = (bool)param[1];
            //}
            if (deadMonster != null)
                Story.StoryManager.Instance.SendEvent(Story.EventType.WinTaskBattle, deadMonster, StartLoad);
            else
                StartLoad();

            LoadWall();

        }
        private void StartLoad()
        {
            if (StaticData.isCompleteTask)
            {
                Exit();
            }
            else
            {
                missionData = Dict.DictDataManager.Instance.tableCopyMissionDao.GetById(StaticData.currFightLevelId);

                if(!string.IsNullOrEmpty(StaticData.missionScene))
                {
                    missionData.SceneName = StaticData.missionScene;
                }

                Debug.Log("[LOGIN] server give me scene:" + missionData.SceneName);

                smallMap.ShowMiniMap();
                smallMap.SetData(missionData);
                //if(!missionLoaded)
                //{
                //    LoadingPanel.Instance.ShowLoading();
                //}
                RoomModelPool.Instance.FlushCache();
                StartCoroutine(_WaitForLoadComplete());
                //if (SceneManager.GetSceneAt(0).name != missionData.SceneName)
                //{

                //}
                //else
                //{
                //    OnLoadComplete();
                //}
                //AudioManager.PlaySceneMusic(missionData.MissionId);
            }
        }

        private IEnumerator _WaitForLoadComplete()
        {
            System.DateTime t = System.DateTime.Now; 
            string sceneName = AssetBundleManager.Instance.GetReplaceSceneName(missionData.SceneName);
            UnityEngine.SceneManagement.Scene runScene = SceneManager.GetSceneByName(sceneName);
            if (runScene.isLoaded)
            {
                for (int i = 0; i < SceneManager.sceneCount; ++i)
                {
                    var s = SceneManager.GetSceneAt(i);
                    if (s.name != sceneName)
                    {
                        var gos = s.GetRootGameObjects();
                        foreach (var g in gos)
                        {
                            g.SetActive(false);
                        }
                    }
                    else
                    {
                        var gos = runScene.GetRootGameObjects();
                        foreach (var g in gos)
                        {
                            g.SetActive(true);
                        }
                        SceneManager.SetActiveScene(runScene);
                    }
                }
                yield return 1;
            }
            else
            {
                //System.DateTime dt = System.DateTime.Now;
                //SceneManager.UnloadScene(SceneName.town);
                //Resources.UnloadUnusedAssets();
                //Debug.Log("unload town scene cost time " + (System.DateTime.Now - dt).TotalMilliseconds);
                yield return StartCoroutine(AssetBundleManager.Instance.LoadSceneAsync(SceneName.sceneFolder
                    + sceneName, sceneName));

                string firstBattleSceneName = Dict.Blo.DictCopyTaskBlo.GetFirstTaskOfMission(missionData.MissionId).SceneName;
                firstBattleSceneName = AssetBundleManager.Instance.GetReplaceSceneName(firstBattleSceneName);
                if(firstBattleSceneName != SceneManager.GetActiveScene().name)
                {
                    yield return StartCoroutine(AssetBundleManager.Instance.LoadSceneAsync(SceneName.sceneFolder
                    + firstBattleSceneName, firstBattleSceneName, true));
                    var sb = SceneManager.GetSceneByName(firstBattleSceneName);
                    GameObject[] bobjs = sb.GetRootGameObjects();
                    foreach (var go in bobjs)
                    {
                        go.SetActive(false);
                    }
                }
                
            }

            if (!isPreLoadHeroLoaded)
            {
                if (missionData.ChapterId == "1" && missionData.MissionId == "1")
                {
                    var preLoadHeroIds = new List<string>();
                    preLoadHeroIds.Add("hero_001");
                    //yield return StartCoroutine(LoadHero("hero_001"));
                    preLoadHeroIds.Add("hero_007");
                    //yield return StartCoroutine(LoadHero("hero_007"));
                    yield return StartCoroutine(LoadHero(preLoadHeroIds));
                }
                isPreLoadHeroLoaded = true;
            }
            yield return 1;
            OnLoadComplete();

            Debug.Log("-----------------------------Load Copy Cost:" + (System.DateTime.Now - t).TotalMilliseconds + "ms");
        }



        private void OnLoadComplete()
        {
            if (RoomManager.curSceneType != SceneType.COPY)
                return;

            RoomUIManager.Instance.gameObject.SetActive(true);
            EasyTouchTool.Instance.ShowJoystick();

            if (!missionLoaded)
            {
                LoadPlayer();
                LoadMonsters();
                LoadBox();
                LoadAreaDataFromTable("mission_" + missionData.MissionId);
                missionLoaded = true;
                LoadingPanel.Instance.HideLoading();
            }
            else
            {
                LoadingPanel.Instance.HideMask(1);
                ResetPosition();
            }
            OnMainCharactorLoaded(charactorManager.GetSelfCharactor().transform);
            smallMap.miniMapComponent.SetMajorCharactor(charactorManager.GetSelfCharactor().transform);
            InitCamera();

            Foreground();
            ManagerController.Instance.cameraTool.SwitchSceneCamera();
            Story.StoryManager.Instance.SendEvent(Story.EventType.AfterEnterCopy, StaticData.currFightLevelId, null);
            AudioManager.PlaySceneMusic(missionData.SceneName);

            LoadWall();
            CameraTool.Instance.ResetSceneBloomEffect();
        }

        void LoadWall()
        {
            string str = "/" + SceneManager.GetActiveScene().name + @"/Models/wall";
            var tran = GameObject.Find(str);
            if (tran != null)
            {
                List<GameObject> list = new List<GameObject>();
                //var childs = tran.transform.GetComponentsInChildren<Transform>();

                var childCount = tran.transform.childCount;

                for(int i=0;i<childCount;++i)
                {
                    var child = tran.transform.GetChild(i);
                    if (child.gameObject.name == tran.name)
                    {
                        continue;
                    }

                    int intText = 0;
                    if (int.TryParse(child.gameObject.name, out intText))
                    {
                        child.gameObject.SetActive(false);
                        list.Add(child.gameObject);
                    }
                }
                
                /*
                foreach (var child in childs)
                {
                    if (child.gameObject.name == tran.name)
                    {
                        continue;
                    }

                    int intText = 0;
                    if (int.TryParse(child.gameObject.name, out intText))
                    {
                        child.gameObject.SetActive(false);
                        list.Add(child.gameObject);
                    }
                }
                */

                if (!string.IsNullOrEmpty(StaticData.currFightLevelId))
                {
                    var wall = Dict.Blo.DictWallBlo.GetOne(StaticData.currFightLevelId);
                    if (wall.MapId == (SceneManager.GetActiveScene().name))
                    {

                        if (!string.IsNullOrEmpty(wall.OpenStr))
                        {
                            var temp0 = wall.OpenStr.Trim();
                            var ss = temp0.Split(new char[1] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
                            foreach (var s in ss)
                            {
                                foreach (var obj in list)
                                {
                                    if (obj.name == s)
                                    {
                                        obj.SetActive(true);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }


        protected override void OnLeave()
        {
            base.OnLeave();

            if (StaticData.isCompleteTask)
            {
                deadMonsters.Clear();
                charactorManager.ClearAll();
                missionLoaded = false;
            }

            this.gameObject.SetActive(false);
            
            uiManager.gameObject.SetActive(false);
        }

        protected override void OnForeground()
        {
        }

        protected override void OnBackground()
        {
        }

        #region camera
        void InitCamera()
        {
            //var taskData = Dict.DictDataManager.Instance.tableCopyMissionDao.GetById(StaticData.currFightLevelId);
            var taskData = Dict.Blo.DictCopyMissionBlo.GetTableCopyMission(StaticData.currFightLevelId);

            var cameraAngle = (float)taskData.CameraAngle;
            /*var height = (float)taskData.Height;
            var depth = (float)taskData.Depth;
             var angle = (float)taskData.FaceTo;
             */

            //var fixedDistance = new Vector3(0f, height, depth);
            //var fixedRotate = new Vector3(cameraAngle, 0f, 0f);
            //var controllerRotate = new Vector3(0, cameraAngle, 0);
            //sceneCamera.Set(fixedDistance, fixedRotate, cameraAngle);

            if (45 == (int)cameraAngle)
            {
                var fixedDistance = new Vector3(-4, 7.8f, -4);
                var fixedRotate = new Vector3(45, cameraAngle, 0);
                //var controllerRotate = new Vector3(0, cameraAngle, 0);
                sceneCamera.Set(fixedDistance, fixedRotate, 45f);
            }
            else if (135 == (int)cameraAngle)
            {
                var fixedDistance = new Vector3(-4, 7.8f, 4);
                var fixedRotate = new Vector3(45, cameraAngle, 0);
                //var controllerRotate = new Vector3(0, cameraAngle, 0);
                sceneCamera.Set(fixedDistance, fixedRotate, 45f);
            }
            else if (225 == (int)cameraAngle)
            {
                var fixedDistance = new Vector3(4, 7.8f, 4);
                var fixedRotate = new Vector3(45, cameraAngle, 0);
                //var controllerRotate = new Vector3(0, cameraAngle, 0);
                sceneCamera.Set(fixedDistance, fixedRotate, 45f);
            }
            else if (315 == (int)cameraAngle)
            {
                var fixedDistance = new Vector3(4, 7.8f, -4);
                var fixedRotate = new Vector3(45, cameraAngle, 0);
                //var controllerRotate = new Vector3(0, cameraAngle, 0);
                sceneCamera.Set(fixedDistance, fixedRotate, 45f);
            }
            else
            {
                Debug.Log("[DEBUG] log error message:" + cameraAngle);
            }



            StaticData.cameraRotate = new Vector3(0, cameraAngle, 0);
        }
        #endregion

        #region Load Charactor
        /// <summary>
        /// 加载Player
        /// </summary>
        public void LoadPlayer()
        {
            //var uid = StaticData.playerData.heroWarUID;
            //var leaderHero = StaticData.playerData.InstPlayerData.GetUIHero(uid);

            //string playerId = uid;
            //string heroId = leaderHero.heroData.id;

            var uid = StaticData.playerData.playerId.ToString();
            var heroId = StaticData.playerData.InstPlayerData.GetBattleCamp(1).hero.heroId;
            var equipId = "";
            if (StaticData.playerData.InstPlayerData.GetBattleCamp(1).equipments[0] != null)
            {
                equipId = StaticData.playerData.InstPlayerData.GetBattleCamp(1).equipments[0].equipId;
            }

            
            charactorManager.CreateSelfPlayer(uid, heroId, equipId, "",StaticData.playerData.curTitle ,"", -1, missionData.FaceTo);
            var self = charactorManager.GetSelfCharactor();
            self.transform.position = new Vector3((float)missionData.BornX, 0, (float)missionData.BornZ);

        }

        public void ResetPosition()
        {
            foreach (var ch in charactorManager.GetCharactors())
            {
                ch.Value.ResetPosition();
            }
        }

        /// <summary>
        /// 加载怪物
        /// </summary>
        public void LoadMonsters()
        {
            var jobs = StaticData.jobs;
            if (jobs != null && jobs.Count > 0)
            {

                foreach (var job in jobs)
                {
                    if (!deadMonsters.Contains(job.taskId))
                    {
                        charactorManager.CreateMonster(job);
                    }
                }
            }
            else
            {
                var monstersIds = Dict.Blo.DictCopyTaskBlo.GetTasksByLevelId(missionData.MissionId);
                foreach (var monster in monstersIds)
                {
                    if (!deadMonsters.Contains(monster.TaskId))
                    {
                        charactorManager.CreateMonster( monster);
                    }
                }
            }
        }

        /// <summary>
        /// 加载copy box
        /// </summary>
        public void LoadBox()
        {
            foreach (var box in StaticData.boxs)
            {
                charactorManager.CreateBox(box);
            }
        }

        /// <summary>
        /// 加载空气墙
        /// </summary>
        //public void LoadAirWall()
        //{
        //    //var wallList = Dict.DictDataManager.Instance.tableCopyAirWallDao.GetByOneIndex(StaticData.currFightLevelId);

        //    var wallList = Dict.Blo.DictCopyAirWallBlo.GetCopyAirWallsByLevelId(StaticData.currFightLevelId);
        //    foreach (var airwall in wallList)
        //    {
        //        charactorManager.CreateAirWall(airwall.BlockId);
        //    }

        //}

        #endregion

        #region animation
        public void StopAllAnimation()
        {
            foreach (var charactor in charactorManager.GetCharactors())
            {
                charactor.Value.StopTo(charactor.Value.transform.position);
                charactor.Value.StopAnimation();
            }
        }

        #endregion

        public void Exit()
        {
            CSCopyLeave leave = new CSCopyLeave();
            leave.chapterId = StaticData.currFightChapterId;
            leave.missionId = StaticData.currFightLevelId;
            leave.taskId = StaticData.currFightTaskId;
            smallMap.HideMiniMap();
            NetAPI.SendHttp(OpDefine.CSCopyLeave, leave, (obj, ok) =>
            {
                if (ok)
                {
                    //清空缓存
                    //增加挑战次数
                    StaticData.isCompleteTask = true;
                    deadMonsters.Clear();
                    charactorManager.ClearAll();
                    missionLoaded = false;
                    StaticData.lastBattleEndMsg = null;
                    AssetLoad.ResourceManager.Instance.UnloadUnusedResources();
                    //Room.RoomManager.Switch(SceneType.TOWN);

                    if (isPreLoadHeroLoaded)
                    {
                        isPreLoadHeroLoaded = false;
                        UnloadAllPreloadHero();
                    }

                    UI.PageManager.instance.currentPage.Close();

                    UI.PageManager.Instance.CheckBattleLeaveOption();

                    LoadingPanel.Instance.HideMask(1f);
                }
            });
        }

        protected override void OnNewCharactorCreate(RoomCharactor rc)
        {
            base.OnNewCharactorCreate(rc);
            rc.SetInView(true);
            rc.SetLodLevel(4);
        }

        #region PreLoad Hero

        bool isPreLoadHeroLoaded = false;

        Dictionary<string, int> resCache = new Dictionary<string, int>();
        Dictionary<string, int> onlyResCache = new Dictionary<string, int>();
        Dictionary<string, int> audioResCache = new Dictionary<string, int>();
        void AddCache(string key, int val = 1)
        {
            if (resCache.ContainsKey(key))
            {
                resCache[key] += val;
            }
            else
            {
                resCache[key] = val;
            }
        }
        void AddOnlyCache(string key, int val = 1)
        {
            if (onlyResCache.ContainsKey(key))
            {
                onlyResCache[key] += val;
            }
            else
            {
                onlyResCache[key] = val;
            }
        }
        void AddAudioCache(string key, int val = 1)
        {
            if (audioResCache.ContainsKey(key))
            {
                audioResCache[key] += val;
            }
            else
            {
                audioResCache[key] = 1;
            }
        }

        IEnumerator PreLoadAssetBundle(string bundle, System.Type t, System.Action onComplete)
        {
            AssetLoad.AssetBundleManager.Instance.LoadAssetBundle(bundle);
            while (!AssetLoad.AssetBundleManager.Instance.IsLoadedAssetBundle(bundle))
            {
                yield return null;
            }
            AssetLoad.AssetBundleManager.Instance.GetAssetFromBundle(bundle, CommonMethod.GetAssetNameFromAssetBundleName(bundle), t);
            if (onComplete != null)
            {
                onComplete();
            }
        }

        private IEnumerator LoadHero(List<string> heroIds)
        {
            foreach (var heroId in heroIds)
            {
                TableHero tb = Dict.Blo.DictHeroBlo.GetTableHero(heroId);
                if (tb != null)
                {
                    AddCache("model/" + tb.resName);
                    AddOnlyCache("model/" + tb.resName + ConstData.extendResPostfix);
                    LoadSkill(tb.SkillId1);
                    LoadSkill(tb.SkillId2);
                    LoadSkill(tb.UltSkillId);
                    LoadUltimateSkill(tb.UltSkillId);

               

                    //AssetBundleManager.Instance.LoadAssetBundle("model/" + tb.resName);
                    //while (!AssetBundleManager.Instance.IsLoadedAssetBundle("model/" + tb.resName))
                    //{
                    //    yield return null;
                    //}
                    //GameObjectPoolManager.Instance.Regist("model/" + tb.resName, tb.resName);
                    //AssetBundleManager.Instance.LoadAssetBundle("model/" + tb.resName + ConstData.extendResPostfix);
                    //while (!AssetBundleManager.Instance.IsLoadedAssetBundle("model/" + tb.resName + ConstData.extendResPostfix))
                    //{
                    //    yield return null;
                    //}
                    //AssetBundleManager.Instance.GetAssetFromBundle("model/" + tb.resName + ConstData.extendResPostfix, tb.resName + ConstData.extendResPostfix, typeof(AnimationClip));
                    //yield return StartCoroutine(LoadSkill(tb.SkillId1));
                    //yield return StartCoroutine(LoadSkill(tb.SkillId2));
                    //yield return StartCoroutine(LoadSkill(tb.UltSkillId));
                    //yield return StartCoroutine(LoadUltimateSkill(tb.UltSkillId));
                }
            }
            int taskCount = 0;
            foreach (var kvp in resCache)
            {
                for (int i = 0; i < kvp.Value; ++i)
                {
                    taskCount++;
                    StartCoroutine(PreLoadAssetBundle(kvp.Key, typeof(GameObject), () => { taskCount--; }));
                }
            }
            foreach (var kvp in onlyResCache)
            {
                for (int i = 0; i < kvp.Value; ++i)
                {
                    taskCount++;
                    StartCoroutine(PreLoadAssetBundle(kvp.Key, typeof(AnimationClip), () => { taskCount--; }));
                }
            }
            foreach (var kvp in audioResCache)
            {
                for (int i = 0; i < kvp.Value; ++i)
                {
                    taskCount++;
                    StartCoroutine(AudioManager.Instance.LoadAudioResource(kvp.Key, () => { taskCount--; }));
                }
            }

            while(taskCount > 0)
            {
                yield return null;
            }
        }

        private IEnumerator LoadParticle(string particleId)
        {
            TableParticle tp = Dict.Blo.DictParticleBlo.GetParticle(particleId);
            if (tp != null)
            {
                string path = "particles/" + tp.ResourcePath;
                AssetBundleManager.Instance.LoadAssetBundle(path);
                while (!AssetBundleManager.Instance.IsLoadedAssetBundle(path))
                {
                    yield return null;
                }
                GameObjectPoolManager.Instance.Regist(path, CommonMethod.GetAssetNameFromAssetBundleName(path));
            }
        }

        private IEnumerator LoadUltiParticle(string url)
        {
            if (!string.IsNullOrEmpty(url))
            {
                string path = "ultimate/" + url;
                AssetBundleManager.Instance.LoadAssetBundle(path);
                while (!AssetBundleManager.Instance.IsLoadedAssetBundle(path))
                {
                    yield return null;
                }
                GameObjectPoolManager.Instance.Regist(path, CommonMethod.GetAssetNameFromAssetBundleName(path));
            }
        }

        private IEnumerator LoadUltiPaint(string url)
        {
            if (!string.IsNullOrEmpty(url))
            {
                AssetBundleManager.Instance.LoadAssetBundle(url);
                while (!AssetBundleManager.Instance.IsLoadedAssetBundle(url))
                {
                    yield return null;
                }
                GameObjectPoolManager.Instance.Regist(url, CommonMethod.GetAssetNameFromAssetBundleName(url));
            }
        }

        private void LoadSkill(string skillId)
        {
            TableSkill ts = Dict.Blo.DictHeroSkillBlo.GetTalbeSkill(skillId);
            if(ts != null)
            {
                foreach (var effect in ts.Effect_array)
                {
                    if (!string.IsNullOrEmpty(effect))
                    {
                        TableParticle tp = Dict.Blo.DictParticleBlo.GetParticle(effect);
                        if (tp != null)
                        {
                            AddCache("particles/" + tp.ResourcePath);
                        }
                    }
                }
                
                if (!string.IsNullOrEmpty(ts.SkillAudio))
                {
                    AddAudioCache(ts.SkillAudio);
                }

                //yield return StartCoroutine(LoadParticle(ts.Effect0));
                //yield return StartCoroutine(LoadParticle(ts.Effect1));
                //yield return StartCoroutine(LoadParticle(ts.Effect2));
                //yield return StartCoroutine(LoadParticle(ts.Effect3));
                //yield return StartCoroutine(LoadParticle(ts.Effect4));
                //if (!string.IsNullOrEmpty(ts.SkillAudio))
                //{
                //    yield return StartCoroutine(AudioManager.Instance.LoadAudioResource(ts.SkillAudio));
                //}
                List<TableSkillCast> castList = Dict.Blo.DictHeroSkillBlo.GetTableSkillCastByHSId(ts.SkillId);
                for (int i = 0; i < castList.Count; ++i)
                {
                    var cast = castList[i];
                    if (!string.IsNullOrEmpty(cast.GroundEffect))
                    {
                        TableParticle tp = Dict.Blo.DictParticleBlo.GetParticle(cast.GroundEffect);
                        if (tp != null)
                        {
                            AddCache("particles/" + tp.ResourcePath);
                        }
                    }
                    if (!string.IsNullOrEmpty(cast.BehitEffSelf))
                    {
                        TableParticle tp = Dict.Blo.DictParticleBlo.GetParticle(cast.BehitEffSelf);
                        if (tp != null)
                        {
                            AddCache("particles/" + tp.ResourcePath);
                        }
                    }
                    if (!string.IsNullOrEmpty(cast.BehitEffectEnemy))
                    {
                        TableParticle tp = Dict.Blo.DictParticleBlo.GetParticle(cast.BehitEffectEnemy);
                        if (tp != null)
                        {
                            AddCache("particles/" + tp.ResourcePath);
                        }
                    }
                    if (!string.IsNullOrEmpty(cast.ProjectId))
                    {
                        TableParticle tp = Dict.Blo.DictParticleBlo.GetParticle(cast.ProjectId);
                        if (tp != null)
                        {
                            AddCache("particles/" + tp.ResourcePath);
                        }
                    }
                    if (!string.IsNullOrEmpty(cast.BehitAudio))
                    {
                        AddAudioCache(cast.BehitAudio);
                    }


                    //yield return StartCoroutine(LoadParticle(cast.GroundEffect));
                    //yield return StartCoroutine(LoadParticle(cast.BehitEffSelf));
                    //yield return StartCoroutine(LoadParticle(cast.BehitEffectEnemy));
                    //yield return StartCoroutine(LoadParticle(cast.ProjectId));
                    //if (!string.IsNullOrEmpty(cast.BehitAudio))
                    //{
                    //    yield return StartCoroutine(AudioManager.Instance.LoadAudioResource(cast.BehitAudio));
                    //}
                }
            }
        }

        private void LoadUltimateSkill(string skillId)
        {
            var dus = Dict.Blo.DictHeroSkillBlo.GetTableUltimateSkill(skillId);
            if (dus != null)
            {
                if (!string.IsNullOrEmpty(dus.FinalBeHitEffect))
                {
                    TableParticle tp = Dict.Blo.DictParticleBlo.GetParticle(dus.FinalBeHitEffect);
                    if (tp != null)
                    {
                        AddCache("particles/" + tp.ResourcePath);
                    }
                }
                if (!string.IsNullOrEmpty(dus.FinalBeHitOwnEffect))
                {
                    TableParticle tp = Dict.Blo.DictParticleBlo.GetParticle(dus.FinalBeHitOwnEffect);
                    if (tp != null)
                    {
                        AddCache("particles/" + tp.ResourcePath);
                    }
                }
                if (!string.IsNullOrEmpty(dus.EffectResourceName))
                {
					AddCache("ultimate/" + dus.EffectResourceName);
                }
				if (!string.IsNullOrEmpty (dus.PaintResUrl)) 
				{
					AddCache (dus.PaintResUrl);
				}
                //yield return StartCoroutine(LoadParticle(dus.FinalBeHitEffect));
                //yield return StartCoroutine(LoadParticle(dus.FinalBeHitOwnEffect));
                //yield return StartCoroutine(LoadUltiParticle(dus.EffectResourceName));
                //yield return StartCoroutine(LoadUltiPaint(dus.PaintResUrl));
            }
        }


        private void UnloadAllPreloadHero()
        {
            foreach (var kvp in resCache)
            {
                for (int i = 0; i < kvp.Value; ++i)
                {
                    AssetLoad.AssetBundleManager.Instance.UnloadAssetBundle(kvp.Key);
                }
            }
            resCache.Clear();
            foreach (var kvp in onlyResCache)
            {
                for (int i = 0; i < kvp.Value; ++i)
                {
                    AssetLoad.AssetBundleManager.Instance.UnloadAssetBundle(kvp.Key);
                }
            }
            onlyResCache.Clear();
            foreach (var kvp in audioResCache)
            {
                for (int i = 0; i < kvp.Value; ++i)
                {
                    AudioManager.Instance.UnloadAudioResource(kvp.Key);
                }
            }
            audioResCache.Clear();

        }
        private void UnloadHero(string heroId)
        {
            TableHero th = Dict.Blo.DictHeroBlo.GetTableHero(heroId);
            if (th != null)
            {
                UnloadUltiSkill(th.UltSkillId);
                UnloadSkill(th.UltSkillId);
                UnloadSkill(th.SkillId2);
                UnloadSkill(th.SkillId1);

                AssetBundleManager.Instance.UnloadAssetBundle("model/" + th.resName + ConstData.extendResPostfix);

                GameObjectPoolManager.Instance.UnRegist("model/" + th.resName);
                AssetBundleManager.Instance.UnloadAssetBundle("model/" + th.resName);
            }
        }

        private void UnloadSkill(string skillId)
        {
            TableSkill ts = Dict.Blo.DictHeroSkillBlo.GetTalbeSkill(skillId);
            if (ts != null)
            {
                UnloadParticle(ts.Effect0);
                UnloadParticle(ts.Effect1);
                UnloadParticle(ts.Effect2);
                UnloadParticle(ts.Effect3);
                UnloadParticle(ts.Effect4);
                if (!string.IsNullOrEmpty(ts.SkillAudio))
                {
                    AudioManager.Instance.UnloadAudioResource(ts.SkillAudio);
                }
                List<TableSkillCast> castList = Dict.Blo.DictHeroSkillBlo.GetTableSkillCastByHSId(skillId);
                for (int i = 0; i < castList.Count; ++i)
                {
                    var cast = castList[i];
                    UnloadParticle(cast.GroundEffect);
                    UnloadParticle(cast.BehitEffSelf);
                    UnloadParticle(cast.BehitEffectEnemy);
                    UnloadParticle(cast.ProjectId);
                    if (!string.IsNullOrEmpty(cast.BehitAudio))
                    {
                        AudioManager.Instance.UnloadAudioResource(cast.BehitAudio);
                    }
                }
            }
        }

        private void UnloadUltiSkill(string skillId)
        {
            var dus = Dict.Blo.DictHeroSkillBlo.GetTableUltimateSkill(skillId);
            if (dus != null)
            {
                UnloadParticle(dus.FinalBeHitEffect);
                UnloadParticle(dus.FinalBeHitOwnEffect);
                UnloadUltiParticle(dus.EffectResourceName);
                UnloadUltiPaint(dus.PaintResUrl);
            }
        }

        private void UnloadParticle(string particleId)
        {
            var tp = Dict.Blo.DictParticleBlo.GetParticle(particleId);
            if (tp != null)
            {
                string path = "particles/" + tp.ResourcePath;
                GameObjectPoolManager.Instance.UnRegist(path);
                AssetBundleManager.Instance.UnloadAssetBundle(path);
            }
        }

        private void UnloadUltiParticle(string url)
        {
            if (!string.IsNullOrEmpty(url))
            {
                string path = "ultimate/" + url;
                GameObjectPoolManager.Instance.UnRegist(path);
                AssetBundleManager.Instance.UnloadAssetBundle(path);
            }
        }

        private void UnloadUltiPaint(string url)
        {
            if (!string.IsNullOrEmpty(url))
            {
                GameObjectPoolManager.Instance.UnRegist(url);
                AssetBundleManager.Instance.UnloadAssetBundle(url);
            }
        }

        #endregion
    }
}
